#include <stdbool.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <sys/un.h> 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/in.h> 
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <ctype.h>

#include "constantes.h"
#include "estructuras.h"
#include "sockets.h"
#include "NIPC.h"
#include "recibirComando.h"

extern int posicionCabezal;
extern RPM;
extern chs glChs;
extern char * algoritmo;

int recibircomando () {
	
	InfoIPC infoIPC;
	int comando;
	char *parametro;
	int arSectores[MAX_QUANTITY_SECTORES] = {-1,-1,-1,-1,-1};
	int colageneral[MAX_QUANTITY_SECTORES] = {-1,-1,-1,-1,-1};
	int colaactiva[MAX_QUANTITY_SECTORES] = {-1,-1,-1,-1,-1};
	int colapasiva[MAX_QUANTITY_SECTORES] = {-1,-1,-1,-1,-1};
	int i,i2,a;
	int sectorInicial,sectorFinal;
	int sector;
	char *datasector;
	int pvez;
	int sectoresverdaderos;
	int atendidos;
	int posAux;

   
	/*************************************************/
	/*************** CREAR Y CONECTAR ****************/
	/***************     CONSOLA      ****************/
	/*************************************************/
	int escucha_consola,Sock_consola;
	struct sockaddr_un local,remote;
	int len,t;
	pid_t child;
	
	
	if ((escucha_consola = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        printf("error al crear socket\n\n");
        exit(EXIT_FAILURE);
	}

	local.sun_family = AF_UNIX;
	strcpy(local.sun_path,"sock_consola");
	unlink(local.sun_path);
		
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(escucha_consola, (struct sockaddr *)&local, len) == -1) {
        perror("bind");
		exit(EXIT_FAILURE);
    }
	
    if (listen(escucha_consola, 5) == -1) {
        perror("listen");
		exit(EXIT_FAILURE);
    }
	
   if((child=fork())==-1){
		perror("fork");
		exit(EXIT_FAILURE);    
    }
    else if (child==0){
		execv("./consola",NULL);	
    }
	
	t = sizeof(remote);
	if ((Sock_consola = accept(escucha_consola, (struct sockaddr *)&remote, &t)) == -1) {
			perror("accept");
			exit(EXIT_FAILURE);
	}
	
	
	while(1){
	
		recibirIPC(Sock_consola, &infoIPC);
		switch(infoIPC.payLoadDescriptor)
		{
			case TRACE:
			
				printf("Datos recibidos: TRACE\n");
				i = 1; 
				arSectores[0]= atoi(strtok(infoIPC.payload," "));
				while(i<4){	
					arSectores[i]= atoi(strtok(NULL," ")); 
					i++;
				}
				
				arSectores[4]=atoi(strtok(NULL,"\t\r\n\0"));
			 
				i=0;
			 
				while(i<5){ 
			 
					printf("arSectores[%i]: %i \n",i,arSectores[i]);
					i=i+1;
				}
			 
		   
				while(arSectores[i]!=-1 && i<5 )
				{  
					if(dentroDeRango(arSectores[i],10000))
					{			
				   i++;
					}
					else
					{
						printf("> Sector fuera de rango\n> Sector nro %d: ",i+1);
					}
				}		
				 
				printf("POSICION ACTUAL: %i\n",posicionCabezal);
				
				posAux=posicionCabezal;
				
				if(!strcmp(algoritmo,"CSCAN")){
					ordenarArrayCSCAN(arSectores,posicionCabezal);	
					posAux=Trace(arSectores,posAux,glChs,0.00015);	
				}					
				else{
					for(i=0;i<MAX_QUANTITY_SECTORES;i++){
						colageneral[i]=arSectores[i];
					}
					i=0;
					pvez=1;
					sectoresverdaderos=0;
					i2=0;
					
					while(i<MAX_QUANTITY_SECTORES){
						if(colageneral[i]!=-1)							
							sectoresverdaderos++;
						i++;		
					}	

					atendidos=0;
					
					while(atendidos!=sectoresverdaderos){
						
						i=0;
						a=0;
						
						if(pvez){
						
							
							while((i<TAMACTIVA)&&(a<MAX_QUANTITY_SECTORES)){
								if(colageneral[a]!=-1)							
								{
									colaactiva[i]=colageneral[a];
									colageneral[a]=-1;
									i++;
								}
								a++;
							}
												
							
							pvez=0;
							atendidos=atendidos+i;
							
						}
						else
							atendidos=atendidos+i2;
				
						i=0;
						a=0;
						while((i<TAMPASIVA)&&(a<MAX_QUANTITY_SECTORES)){
							if(colageneral[a]!=-1)							
							{
								colapasiva[i]=colageneral[a];
								colageneral[a]=-1;
								i++;
							}
							a++;
						}
						i2=i;
											
						ordenarArraySCAN(colaactiva,posAux);	 
						posAux=Trace(colaactiva,posAux,glChs,0.00015);
						
						for(i=0;i<MAX_QUANTITY_SECTORES;i++){
							colaactiva[i]=colapasiva[i];
						}
					
						for(i=0;i<MAX_QUANTITY_SECTORES;i++){
							colapasiva[i]=-1;
						}
						
					} 
				
				}  
				break;
			
			case INFO:
			
				printf("Datos recibidos: INFO\n");
				printf("POSICION ACTUAL: %i\n",posicionCabezal);
				break;
			
			case CLEAN:
					
				printf("Datos recibidos: CLEAN\n");
				sectorInicial=atoi(strtok(infoIPC.payload," "));
				sectorFinal= atoi(strtok(NULL," "));
				Clean(sectorInicial,sectorFinal);
				break;
				
			default:	
				break;
		
		}	
		
	}


	
	/*free(parametro);
	printf("\nMENU CONSOLA PPD \n");
	printf("------------------\n");
	printf("\n\nIngrese alguno de los siguientes comandos\n\n");
	printf("1)trace S1 [S2 S3 S4 S5] \n");
	printf("2)info \n");
	printf("3)clean S1 S2 \n");
	printf("\n");
   */
	
}


 
int dentroDeRango(int unSector, int sectores_totales_vda)
{ 
	int resultado=0;
	sectores_totales_vda--;
	if(unSector <= sectores_totales_vda && unSector >= 0)
	{
		resultado = 1;
	}

	return resultado;
}		

int esnum(char letra){
      
     if((isdigit(letra))) 
      return 0;
     
     return 1;   
}


